package aso.fighting_groups;

import java.awt.Color;

import javax.swing.JFrame;

import sim.display.Controller;
import sim.display.Display2D;
import sim.display.GUIState;
import sim.engine.SimState;
import sim.portrayal.grid.FastValueGridPortrayal2D;
import sim.portrayal.grid.SparseGridPortrayal2D;
import sim.portrayal.simple.MovablePortrayal2D;

/**
 * GUI class.
 */
public class FightingGroupsWithUI extends GUIState {

    /**
     * @return the name of the Application
     */
    public static String getName() {
        return "FightingGroups";
    }

    /**
     * @param args
     *            command line arguments
     */
    public static void main(final String[] args) {
        new FightingGroupsWithUI().createController();
    }

    /**
     * The array of agent portrayals.
     */
    private SparseGridPortrayal2D[] agentPortrayals;
    /**
     * The display.
     */
    private Display2D display;
    /**
     * The frame.
     */
    private JFrame displayFrame;
    /**
     * The food portrayal.
     */
    private FastValueGridPortrayal2D foodPortrayal = new FastValueGridPortrayal2D("Food");
    /**
     * The smel portrayal.
     */
    private FastValueGridPortrayal2D smellPortrayal = new FastValueGridPortrayal2D("Smell");

    /**
     * Creates the GUI with the default simulation.
     */
    public FightingGroupsWithUI() {
        this(new FightingGroups(System.currentTimeMillis()));
    }

    /**
     * @param state
     *            a SimState
     */
    public FightingGroupsWithUI(final SimState state) {
        super(state);
        initAgentPortrayals();
    }

    @Override
    public final Object getSimulationInspectedObject() {
        return state;
    }

    @Override
    public final void init(final Controller c) {
        super.init(c);

        // Make the Display2D. We'll have it display stuff later.
        display = new Display2D(600, 600, this); 
        displayFrame = display.createFrame();
        displayFrame.setTitle(displayFrame.getTitle());
        c.registerFrame(displayFrame); // register the frame so it appears in
                                       // the "Display" list
        displayFrame.setVisible(true);

        // specify the backdrop color -- what gets painted behind the displays
        display.setBackdrop(Color.black);
    }

    /**
     * Initializes Agent portrayals.
     */
    private void initAgentPortrayals() {
        agentPortrayals = new SparseGridPortrayal2D[((FightingGroups) state).getTeamCount()];

        for (int i = 0; i < ((FightingGroups) state).getTeamCount(); ++i) {
            agentPortrayals[i] = new SparseGridPortrayal2D();
        }
    }

    @Override
    public final void load(final SimState state) {
        super.load(state);
        setupPortrayals();
    }

    @Override
    public final void quit() {
        super.quit();

        if (displayFrame != null) {
            displayFrame.dispose();
        }
        displayFrame = null; // let gc
        display = null; // let gc
    }

    /**
     * Sets up the portrayals.
     */
    private void setupPortrayals() {
        initAgentPortrayals();

        display.detatchAll();

        // attach the portrayals
        display.attach(smellPortrayal, "Smell");
        display.attach(foodPortrayal, "Food");

        for (int i = 0; i < ((FightingGroups) state).getTeamCount(); ++i) {
            display.attach(agentPortrayals[i], "Team " + i);
        }

        for (int i = 0; i < ((FightingGroups) state).getTeamCount(); ++i) {
            agentPortrayals[i].setField(((FightingGroups) state).getAgentGrid()[i]);
            agentPortrayals[i].setPortrayalForAll(new MovablePortrayal2D(new sim.portrayal.simple.OvalPortrayal2D(new Color(state.random.nextFloat(), state.random.nextFloat(), state.random.nextFloat()))));
        }

        smellPortrayal.setField(((FightingGroups) state).getSmellGrid());
        smellPortrayal.setMap(new sim.util.gui.SimpleColorMap(0, ((FightingGroups) state).getMaxSmell(), new Color(0.0f, 0.0f, 0.0f, 0.0f), Color.yellow));

        foodPortrayal.setField(((FightingGroups) state).getFoodGrid());
        foodPortrayal.setMap(new sim.util.gui.SimpleColorMap(0, ((FightingGroups) state).getMaxFood(), new Color(0.0f, 0.0f, 0.0f, 0.0f), Color.green));

        display.reset();

        display.repaint();
    }

    @Override
    public final void start() {
        super.start();
        setupPortrayals();
    }
}
